package com.zut.edu.http;

import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class OkhttpHelper {

    private static OkHttpClient okHttpClient;
    private Gson gson;
    private Handler handler ;


    private OkhttpHelper() {
        okHttpClient = new OkHttpClient().newBuilder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .callTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .build();

        gson = new Gson();
        handler = new Handler(Looper.getMainLooper());

    }

    public static OkhttpHelper getInstance(){

        return new OkhttpHelper();
    }

    public void get(String url,Map<String,Object> params, BaseCallback callback){//get()

        Request request = buildRequest(url,params, HttpMethodType.GET);
        baseRequest(request,callback);
    }

    public void post(String url, Map<String,Object> params, BaseCallback callback){//post()

        Request request = buildRequest(url,params, HttpMethodType.POST);
        baseRequest(request,callback);

    }

    public void baseRequest(final Request request, final BaseCallback callback){//回调绑定(到request)


        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                callbackfailure(callback ,call ,e );
            }


            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                if(response.isSuccessful()){
                    String resultStr = response.body().string();
                    JSONObject jsonObject = JSON.parseObject(resultStr);
//                  JSONObject jsonObject2 = JSON.parseObject(jsonObject.getString("result"));
                    Object object = gson.fromJson(jsonObject .getString("data"),callback.mType);
                    int code = Integer.parseInt(jsonObject .getString("code"));
                    if(callback.mType == String.class){
                            callbackSuccess( callback , call,  response,  resultStr, code );
                    }
                    else{
                        try{
                            callbackSuccess( callback , call,  response,  object, code );
                        }
                        catch (JsonParseException e){
                            callbackerror(callback,call,response,e);
                        }
                    }
                }
                else{
                    callbackerror(callback,call,response,null);
                }

            }
        });
    }

    private Request buildRequest(String url,Map<String,Object> params,HttpMethodType methodType){//构建request

        Request.Builder builder = new Request.Builder();
        builder.url(url);
        if(methodType == HttpMethodType.GET){
            url = buildUrlParams(url,params);//get拼接参数
            builder.url(url);
            builder.get();
        }
        else if(methodType == HttpMethodType.POST){
            FormBody formBody = buildFormData(params);
            builder.post(formBody);
        }

        return builder.build();
    }

    private FormBody buildFormData(Map<String,Object> params){//构建post请求体的参数

        FormBody.Builder builder = new FormBody.Builder();
        for(Map.Entry<String,Object> entry : params.entrySet()){
            builder.add(entry.getKey(), entry.getValue().toString());
        }

        return builder.build();
    }


    private String buildUrlParams(String url ,Map<String,Object> params) {//构建get的参数

        if(params == null)
            params = new HashMap<>(1);

        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            sb.append(entry.getKey() + "=" + (entry.getValue()==null?"":entry.getValue().toString()));
            sb.append("&");
        }
        String s = sb.toString();
        if (s.endsWith("&")) {
            s = s.substring(0, s.length() - 1);
        }

        if(url.indexOf("?")>0){
            url = url +"&"+s;
        }else{
            url = url +"?"+s;
        }

        return url;
    }

    private void callbackSuccess(final  BaseCallback callback ,final Call call, final Response response, final Object obj ,final int code) throws IOException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            callback.onSuccess(call,response,obj,code);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }).start();
    }

    private void callbackfailure(final BaseCallback callback , final Call call , final IOException e){
        new Thread(new Runnable() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        callback.onFailure(call,e);
                    }
                });
            }
        }).start();
    }

    private void callbackerror(final BaseCallback callback,final Call call,final Response response,final JsonParseException e){
        new Thread(new Runnable() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        callback.onError(call,response,response.code(),e);
                    }
                });
            }
        }).start();
    }

    enum HttpMethodType{//枚举分类
        GET,POST
    }
}
